﻿#region usings
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using InsuranceAdjuster.Web.Models;
#endregion
namespace InsuranceAdjuster.Web.Services {


    [EnableClientAccess()]
    public class SLInsuranceDomainService : LinqToEntitiesDomainService<SilverlightInsuranceEntities> {

       /// <summary>
        /// Get Detla Appointments
        /// </summary>
        /// <param name="clientAnchor"></param>
        /// <returns></returns>
        public IQueryable<AdjusterAppointment> GetAdjusterAppointmentsByDelta(DateTime clientAnchor) {
            var query = from aa in ObjectContext.AdjusterAppointments
                              where aa.LastEdit > clientAnchor
                             select aa;
            return query;
        }


        /// <summary>
        /// Get Deleted Appointments
        /// </summary>
        /// <param name="clientAnchor"></param>
        /// <returns></returns>
        public IQueryable<AdjusterAppointment> GetDeletedAdjusterAppointments(DateTime clientAnchor) {
            var query = from aat in ObjectContext.AdjusterAppointment_Tombstone
                        where aat.UpdateTimestamp > clientAnchor
                        select new { aat.AdjusterAppointmentGuid, aat.Adjuster_Id };

            var output = new List<AdjusterAppointment>();

            foreach (var Item in query)
                output.Add(new AdjusterAppointment() {
                    AppointmentGuid = Item.AdjusterAppointmentGuid
                                                     ,
                    Adjuster_Id = new Guid(Item.Adjuster_Id)
                });

            return output.AsQueryable();
        }





        public IQueryable<AdjusterAppointment> GetAdjusterAppointments() {
            return this.ObjectContext.AdjusterAppointments.Include("Claim").OrderBy(e => e.AppointmentDateTime);
        }

        public IQueryable<AdjusterAppointment> GetAdjusterAppointmentsByAdjusterId(string adjuster_Id) {
            return this.ObjectContext.AdjusterAppointments.Include("Claim").Where(e => e.Adjuster_Id == Guid.Parse(adjuster_Id))
                                                                           .OrderBy(e => e.AppointmentDateTime);
        }

        public void InsertAdjusterAppointment(AdjusterAppointment adjusterAppointment) {
            if ((adjusterAppointment.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(adjusterAppointment, EntityState.Added);
            }
            else {
                this.ObjectContext.AdjusterAppointments.AddObject(adjusterAppointment);
            }
        }

        public void UpdateAdjusterAppointment(AdjusterAppointment currentAdjusterAppointment) {
            this.ObjectContext.AdjusterAppointments.AttachAsModified(currentAdjusterAppointment, this.ChangeSet.GetOriginal(currentAdjusterAppointment));
        }

        public void DeleteAdjusterAppointment(AdjusterAppointment adjusterAppointment) {
            if ((adjusterAppointment.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(adjusterAppointment, EntityState.Deleted);
            }
            else {
                this.ObjectContext.AdjusterAppointments.Attach(adjusterAppointment);
                this.ObjectContext.AdjusterAppointments.DeleteObject(adjusterAppointment);
            }
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'BranchOffices' query.
        public IQueryable<BranchOffice> GetBranchOffices() {
            return this.ObjectContext.BranchOffices.Include("BranchStyles");
        }

        public void InsertBranchOffice(BranchOffice branchOffice) {
            if ((branchOffice.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(branchOffice, EntityState.Added);
            }
            else {
                this.ObjectContext.BranchOffices.AddObject(branchOffice);
            }
        }

        public void UpdateBranchOffice(BranchOffice currentBranchOffice) {
            this.ObjectContext.BranchOffices.AttachAsModified(currentBranchOffice, this.ChangeSet.GetOriginal(currentBranchOffice));
        }

        public void DeleteBranchOffice(BranchOffice branchOffice) {
            if ((branchOffice.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(branchOffice, EntityState.Deleted);
            }
            else {
                this.ObjectContext.BranchOffices.Attach(branchOffice);
                this.ObjectContext.BranchOffices.DeleteObject(branchOffice);
            }
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'BranchStyles' query.
        public IQueryable<BranchStyle> GetBranchStyles() {
            return this.ObjectContext.BranchStyles;
        }

        public void InsertBranchStyle(BranchStyle branchStyle) {
            if ((branchStyle.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(branchStyle, EntityState.Added);
            }
            else {
                this.ObjectContext.BranchStyles.AddObject(branchStyle);
            }
        }

        public void UpdateBranchStyle(BranchStyle currentBranchStyle) {
            this.ObjectContext.BranchStyles.AttachAsModified(currentBranchStyle, this.ChangeSet.GetOriginal(currentBranchStyle));
        }

        public void DeleteBranchStyle(BranchStyle branchStyle) {
            if ((branchStyle.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(branchStyle, EntityState.Deleted);
            }
            else {
                this.ObjectContext.BranchStyles.Attach(branchStyle);
                this.ObjectContext.BranchStyles.DeleteObject(branchStyle);
            }
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'BranchUsers' query.
        public IQueryable<BranchUser> GetBranchUsers() {
            return this.ObjectContext.BranchUsers;
        }

        public void InsertBranchUser(BranchUser branchUser) {
            if ((branchUser.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(branchUser, EntityState.Added);
            }
            else {
                this.ObjectContext.BranchUsers.AddObject(branchUser);
            }
        }

        public void UpdateBranchUser(BranchUser currentBranchUser) {
            this.ObjectContext.BranchUsers.AttachAsModified(currentBranchUser, this.ChangeSet.GetOriginal(currentBranchUser));
        }

        public void DeleteBranchUser(BranchUser branchUser) {
            if ((branchUser.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(branchUser, EntityState.Deleted);
            }
            else {
                this.ObjectContext.BranchUsers.Attach(branchUser);
                this.ObjectContext.BranchUsers.DeleteObject(branchUser);
            }
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'Claims' query.
        public IQueryable<Claim> GetClaims() {
            return this.ObjectContext.Claims;
        }

        /// <summary>
        /// Get a specific Claim
        /// </summary>
        /// <param name="claimId"></param>
        /// <returns></returns>
        public IQueryable<Claim> GetClaimById(Guid claimGuid) {
            //var MyClaims = ObjectContext.Claims.ToList();

            return ObjectContext.Claims.Where(e => e.ClaimGuid == claimGuid);
        }

        public void InsertClaim(Claim claim) {
            if ((claim.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(claim, EntityState.Added);
            }
            else {
                this.ObjectContext.Claims.AddObject(claim);
            }
        }

        public void UpdateClaim(Claim currentClaim) {
            this.ObjectContext.Claims.AttachAsModified(currentClaim, this.ChangeSet.GetOriginal(currentClaim));
        }

        public void DeleteClaim(Claim claim) {
            if ((claim.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(claim, EntityState.Deleted);
            }
            else {
                this.ObjectContext.Claims.Attach(claim);
                this.ObjectContext.Claims.DeleteObject(claim);
            }
        }

        public IQueryable<Claim> GetClaimsByDelta(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.Claims
                        where myEntities.LastEdit > clientAnchor
                        select myEntities;
            return query;
        }

        public IQueryable<Claim> GetDeletedClaims(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.Claim_Tombstone
                        where myEntities.UpdateTimestamp > clientAnchor
                        select new { EntityGuid = myEntities.ClaimGuid, PartitionHash = myEntities.AdjusterId };

            var output = new List<Claim>();

            foreach (var Item in query)
                output.Add(new Claim() { ClaimGuid = Item.EntityGuid });

            return output.AsQueryable();
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'ClaimDamages' query.
        public IQueryable<ClaimDamage> GetClaimDamages() {
            return this.ObjectContext.ClaimDamages;
        }

        public IQueryable<ClaimDamage> GetClaimDamagesByClaimId(Guid claimGuid) {
            return this.ObjectContext.ClaimDamages.Where(e => e.ClaimGuid == claimGuid);
        }

        public void InsertClaimDamage(ClaimDamage claimDamage) {
            if ((claimDamage.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(claimDamage, EntityState.Added);
            }
            else {
                this.ObjectContext.ClaimDamages.AddObject(claimDamage);
            }
        }

        public void UpdateClaimDamage(ClaimDamage currentClaimDamage) {
            this.ObjectContext.ClaimDamages.AttachAsModified(currentClaimDamage, this.ChangeSet.GetOriginal(currentClaimDamage));
        }

        public void DeleteClaimDamage(ClaimDamage claimDamage) {
            if ((claimDamage.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(claimDamage, EntityState.Deleted);
            }
            else {
                this.ObjectContext.ClaimDamages.Attach(claimDamage);
                this.ObjectContext.ClaimDamages.DeleteObject(claimDamage);
            }
        }

        public IQueryable<ClaimDamage> GetClaimDamagesByDelta(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.ClaimDamages
                        where myEntities.LastEdit > clientAnchor
                        select myEntities;
            return query;
        }

        public IQueryable<ClaimDamage> GetDeletedClaimDamages(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.ClaimDamage_Tombstone
                        where myEntities.UpdateTimestamp > clientAnchor
                        select new { EntityGuid = myEntities.ClaimDamageGuid, PartitionHash = myEntities.AdjusterId };

            var output = new List<ClaimDamage>();

            foreach (var Item in query)
                output.Add(new ClaimDamage() { ClaimDamageGuid = Item.EntityGuid });

            return output.AsQueryable();
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'ClaimStatus' query.
        public IQueryable<ClaimStatu> GetClaimStatus() {
            return this.ObjectContext.ClaimStatus;
        }

        public void InsertClaimStatu(ClaimStatu claimStatu) {
            if ((claimStatu.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(claimStatu, EntityState.Added);
            }
            else {
                this.ObjectContext.ClaimStatus.AddObject(claimStatu);
            }
        }

        public void UpdateClaimStatu(ClaimStatu currentClaimStatu) {
            this.ObjectContext.ClaimStatus.AttachAsModified(currentClaimStatu, this.ChangeSet.GetOriginal(currentClaimStatu));
        }

        public void DeleteClaimStatu(ClaimStatu claimStatu) {
            if ((claimStatu.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(claimStatu, EntityState.Deleted);
            }
            else {
                this.ObjectContext.ClaimStatus.Attach(claimStatu);
                this.ObjectContext.ClaimStatus.DeleteObject(claimStatu);
            }
        }

        public IQueryable<ClaimStatu> GetClaimStatusesByDelta(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.ClaimStatus
                        where myEntities.LastEdit > clientAnchor
                        select myEntities;
            return query;
        }

        public IQueryable<ClaimStatu> GetDeletedClaimStatuses(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.ClaimStatus_Tombstone
                        where myEntities.UpdateTimestamp > clientAnchor
                        select new { EntityGuid = myEntities.ClaimStatusGuid, PartitionHash = Guid.Empty };

            var output = new List<ClaimStatu>();

            foreach (var Item in query)
                output.Add(new ClaimStatu() { ClaimStatusGuid = Item.EntityGuid });

            return output.AsQueryable();
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'NextTableIds' query.
        public IQueryable<NextTableId> GetNextTableIds() {
            return this.ObjectContext.NextTableIds;
        }

        public void InsertNextTableId(NextTableId nextTableId) {
            if ((nextTableId.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(nextTableId, EntityState.Added);
            }
            else {
                this.ObjectContext.NextTableIds.AddObject(nextTableId);
            }
        }

        public void UpdateNextTableId(NextTableId currentNextTableId) {
            this.ObjectContext.NextTableIds.AttachAsModified(currentNextTableId, this.ChangeSet.GetOriginal(currentNextTableId));
        }

        public void DeleteNextTableId(NextTableId nextTableId) {
            if ((nextTableId.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(nextTableId, EntityState.Deleted);
            }
            else {
                this.ObjectContext.NextTableIds.Attach(nextTableId);
                this.ObjectContext.NextTableIds.DeleteObject(nextTableId);
            }
        }

        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'StandardVehicleImages' query.
        public IQueryable<StandardVehicleImage> GetStandardVehicleImages() {
            return this.ObjectContext.StandardVehicleImages.Where(x => x.Year >= _CutoffYear);
        }

        public IQueryable<StandardVehicleImage> GetStandardVehicleImageByBodyType(string bodyType_Id) {
            return this.ObjectContext.StandardVehicleImages.Where(e => e.BodyType_Id == bodyType_Id);
        }
        public IQueryable<StandardVehicleImage> GetVehicleInformation() {
            return this.ObjectContext.StandardVehicleImages.Where(x => x.Year >= _CutoffYear);
        }
        public void InsertStandardVehicleImage(StandardVehicleImage standardVehicleImage) {
            if ((standardVehicleImage.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(standardVehicleImage, EntityState.Added);
            }
            else {
                this.ObjectContext.StandardVehicleImages.AddObject(standardVehicleImage);
            }
        }

        public void UpdateStandardVehicleImage(StandardVehicleImage currentStandardVehicleImage) {
            this.ObjectContext.StandardVehicleImages.AttachAsModified(currentStandardVehicleImage, this.ChangeSet.GetOriginal(currentStandardVehicleImage));
        }

        public void DeleteStandardVehicleImage(StandardVehicleImage standardVehicleImage) {
            if ((standardVehicleImage.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(standardVehicleImage, EntityState.Deleted);
            }
            else {
                this.ObjectContext.StandardVehicleImages.Attach(standardVehicleImage);
                this.ObjectContext.StandardVehicleImages.DeleteObject(standardVehicleImage);
            }
        }

        public IQueryable<StandardVehicleImage> GetVehiclesByDelta(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.StandardVehicleImages
                        where myEntities.Year >= _CutoffYear
                        where myEntities.LastEdit > clientAnchor
                        select myEntities;
            return query;
        }

        public IQueryable<StandardVehicleImage> GetDeletedVehicles(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.StandardVehicleImage_Tombstone
                        where myEntities.UpdateTimestamp > clientAnchor
                        select new { EntityGuid = myEntities.StandardVehicleGuid};

            var output = new List<StandardVehicleImage>();

            foreach (var Item in query)
                output.Add(new StandardVehicleImage() { StandardVehicleGuid = Item.EntityGuid });

            return output.AsQueryable();
        }

        public IQueryable<VehicleReferencePhoto> GetVehicleReferencePhotoByGuid(Guid entityGuid) {
            return ObjectContext.VehicleReferencePhotoes.Where(e => e.VehicleReferencePhotoGuid == entityGuid);
        }

        public IQueryable<VehicleReferencePhoto> GetVehicleReferencePhotos() {
            return this.ObjectContext.VehicleReferencePhotoes;
        }

        public IQueryable<VehicleReferencePhoto> GetVehicleImage(int year, string make, string model) {
            return new DAL().GetVehicleImage(year, make, model);
        }
        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'States' query.
        public IQueryable<State> GetStates() {
            return this.ObjectContext.States;
        }

        public void InsertState(State state) {
            if ((state.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(state, EntityState.Added);
            }
            else {
                this.ObjectContext.States.AddObject(state);
            }
        }

        public void UpdateState(State currentState) {
            this.ObjectContext.States.AttachAsModified(currentState, this.ChangeSet.GetOriginal(currentState));
        }

        public void DeleteState(State state) {
            if ((state.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(state, EntityState.Deleted);
            }
            else {
                this.ObjectContext.States.Attach(state);
                this.ObjectContext.States.DeleteObject(state);
            }
        }


        public IQueryable<State> GetStatesByDelta(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.States
                        where myEntities.LastEdit > clientAnchor
                        select myEntities;
            return query;
        }

        public IQueryable<State> GetDeletedStates(DateTime clientAnchor) {
            var query = from myEntities in ObjectContext.State_Tombstone
                        where myEntities.UpdateTimestamp > clientAnchor
                        select new { EntityGuid = myEntities.StateGuid, PartitionHash = Guid.Empty };

            var output = new List<State>();

            foreach (var Item in query)
                output.Add(new State() { StateGuid = Item.EntityGuid });

            return output.AsQueryable();
        }


        // TODO:
        // Consider constraining the results of your query method.  If you need additional input you can
        // add parameters to this method or create additional query methods with different names.
        // To support paging you will need to add ordering to the 'VehicleBodyTypes' query.
        public IQueryable<VehicleBodyType> GetVehicleBodyTypes() {
            return this.ObjectContext.VehicleBodyTypes;
        }

        public void InsertVehicleBodyType(VehicleBodyType vehicleBodyType) {
            if ((vehicleBodyType.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(vehicleBodyType, EntityState.Added);
            }
            else {
                this.ObjectContext.VehicleBodyTypes.AddObject(vehicleBodyType);
            }
        }

        public void UpdateVehicleBodyType(VehicleBodyType currentVehicleBodyType) {
            this.ObjectContext.VehicleBodyTypes.AttachAsModified(currentVehicleBodyType, this.ChangeSet.GetOriginal(currentVehicleBodyType));
        }

        public void DeleteVehicleBodyType(VehicleBodyType vehicleBodyType) {
            if ((vehicleBodyType.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(vehicleBodyType, EntityState.Deleted);
            }
            else {
                this.ObjectContext.VehicleBodyTypes.Attach(vehicleBodyType);
                this.ObjectContext.VehicleBodyTypes.DeleteObject(vehicleBodyType);
            }
        }

        private int _CutoffYear = 1990;
    }
}


